/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package CodeGenerator;

import Data.MyParams;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author DavidUser
 */
public class GenerateXMLFromCode {
    
    protected String s_Name;/**<Stores the name of template code*/
    protected String s_InputText;/**<Code we need to transform*/
    protected String s_GeneratedText;/**<Transfomred code*/
    protected String s_FoundVariables;/**<Parameters we want to be make repleaceable*/
    protected String s_Language; /**<Language of the code*/
    protected boolean b_Error; /**<Parameters selected wrong?*/
    protected String s_Error; /**<Which parameters are not good!*/
    protected String s_Tag; /**<Stores tags, to be able to find it quicker*/
    
    //formating variables
    //spaces
        protected final String codeSpace = "\t" + "\t";
        protected final String newLine = "\n\r";
   //XML frames
        protected final String oneEntryStart = "<oneEntry>";
        protected final String oneEntryEnd = "</oneEntry>";
        protected final String codeStart = "\t" + "<code>";
        protected final String codeEnd = "\t" + "</code>";
        protected final String nameStart = "\t" + "<name>";
        protected final String nameEnd = "</name>";
        protected final String languageStart = "\t" + "<language>";
        protected final String languageEnd = "</language>";
        protected final String paramStart = "\t" + "<param>";
        protected final String paramEnd = "</param>";
        protected final String tagStart = "\t" + "<tag>";
        protected final String tagEnd = "</tag>";
    
    /*
     * Constructor
     */
    public GenerateXMLFromCode(){
        Init();
    }
    
    /*
     * Inits variables, called by constructor
     */
    protected void Init(){
        s_Name = "";
        s_InputText = "";
        s_GeneratedText = "";
        s_FoundVariables = "";
        s_Error = "";
        b_Error = false;
    }
    
    /*
     * Set the name of template code
     * 
     * @param name - the name we want to use
     */
    public void SetName(String name){
        s_Name = name;
    }
    
    /*
     * Set language
     * 
     * @param name - the name we want to use
     */
    public void SetLanguage(String language){
        s_Language = language;
    }
    
    /*
     * Set the code we want to use. It calls cconverttext automatically
     * 
     * @param input - the code we want to transform
     */
    public void SetInputText(String input){
        s_InputText = input;
        ConvertText();
    }
    
    /*
     * Set parameter tag. It calls converter
     */
    public void SetTag(String tag){
        s_Tag = tag;
        ConvertTag();
    }
        
    /*
     * Returns the converted text
     * 
     * @return - the converted text
     */
    public String GetGeneratedText(){
        return s_GeneratedText;
    }
    /*
     * Check if parameter names and chars are selected right
     * 
     * @return true - if selections are good, else text needs to be edited
     */
    public boolean GetError(){
        return b_Error;
    }
    
    /*
     * Return the string which contains the problementic parameters
     */
    public String GetErrorString(){
        return s_Error;
    }
    
    /*
     * Converts the code to xml code! Called by SetInputText
     */
    protected void ConvertText(){
        //Strings we want to use in our code
        
        
        //Save parameters list
        List<MyParams> ls = new ArrayList<MyParams>();
        ls.clear();
        SearchParam(ls);
        
        //String to convert our code
        //start
        s_GeneratedText = newLine + oneEntryStart + newLine;
        //name
        s_GeneratedText = s_GeneratedText + nameStart + s_Name + nameEnd + newLine;
        //Tags
        s_GeneratedText = s_GeneratedText + s_Tag;
        //language
        s_GeneratedText = s_GeneratedText + languageStart + s_Language + languageEnd + newLine;
        //parameter
        AddParams(ls);
        //codepart
        CodeFormat();
        s_GeneratedText = s_GeneratedText + codeStart + newLine + "\t\t" + s_InputText + newLine + codeEnd + newLine;
        //end
        s_GeneratedText = s_GeneratedText + oneEntryEnd;
   }
   
   /*
    * Search the replecable parameters in the code
    */ 
   protected void SearchParam(List<MyParams> x){
       int indexInText = 0;
       int length = s_InputText.length();
       int startIndex = 0;
       int endIndex;
       char frameChar = '0';
       while (indexInText + 3 < length){
           //find start frame
           while (indexInText + 2 < length){
               //Search for end frame
               String sub = s_InputText.substring(indexInText, indexInText + 3);
               if (sub.charAt(0) == '<' && Character.isLetter(sub.charAt(1)) && sub.charAt(2) == '>' ){
                   frameChar = sub.charAt(1);
                   indexInText = indexInText + 3;
                   startIndex = indexInText;
                   break;
               }
               else 
                   indexInText++;
           }
           //find end frame
           while (indexInText + 3 < length){
               //Search for end frame
               String sub = s_InputText.substring(indexInText, indexInText + 4);
               if (sub.charAt(0) == '<' && sub.charAt(1) == '/' && sub.charAt(2) == frameChar && sub.charAt(3) == '>' ){
                   endIndex = indexInText--;
                   MyParams param = new MyParams();
                   param.SetName(s_InputText.substring(startIndex, endIndex));
                   param.SetXmlChar(frameChar);
                   if (!CheckIfParamAlreadyExist(x,param)){
                    x.add(param);
                   }
                   indexInText = indexInText + 4;
                   break;
               }
               else 
                   indexInText++;
           }
       }
       ErrorWithParametes(x);
  }
   
   /*
    * Params converted to text
    */ 
   protected void AddParams(List<MyParams> x){
      
      
      for (MyParams s : x){
          s_FoundVariables = s_FoundVariables + s.GetName() + newLine;
          s_GeneratedText = s_GeneratedText + paramStart + s.GetName() + paramEnd + newLine;
      }
    }
   
   /*
    * Checks if parameters names and chars are different in the list
    */
   protected void ErrorWithParametes(List<MyParams> x){
       if (x.size() <= 1) return;
       for (int i = 0; i < x.size() - 1 ; i++){
           for (int k = i+1; k < x.size(); k++){
               if ((x.get(i).GetName().equals(x.get(k).GetName())) || (x.get(i).GetXMLChar() == x.get(k).GetXMLChar())){
                   b_Error = true; 
                   s_Error = s_Error + "Error with:\t" + x.get(i).GetName() + "<" + x.get(i).GetXMLChar() + "> " + x.get(k).GetName() + "<" + x.get(k).GetXMLChar() + ">" + newLine;
               }
           }
       }
   }
   
   /*
    * Convert tags to xml format
    */
   protected void ConvertTag(){
       if (s_Tag.equals("")) return;
       String[] tags = s_Tag.split(" ");
       String output = "";
       for (String s : tags)
           output = output + tagStart +  s + tagEnd + newLine;
       s_Tag = output;
   }
   
   /*
    * Formating the code to be readable
    */
   protected void CodeFormat(){
       String[] result = s_InputText.split("\n");
       String output = "";
       for (String s : result)
           output = output + s + "\r\n\t\t";
       s_InputText = output.trim();
   }
           
   /*
    * Return params compressed to string
    *
    * @return - string of the params
    */
   public String GetParams(){
       return s_FoundVariables;
   }
   
   /*
    * Check if newly found param is already exist in the list
    */
   protected boolean CheckIfParamAlreadyExist(List<MyParams> x, MyParams newParam){
       if (x.isEmpty()) return false; 
       for (int i = 0; i < x.size(); i++){
           if (x.get(i).GetName().equals(newParam.GetName()) && (x.get(i).GetXMLChar() == newParam.GetXMLChar()))
               return true;
       }
       return false;
   }
}